// src/service/operLog.service.ts
import connection from "@/app/database";
import { ResultSetHeader, RowDataPacket } from "mysql2";
import { Context } from "koa";

class OperLogService {
  // 添加操作日志
  async add(operLog: API.OperLogParams) {
    try {
      const statement = `
        INSERT INTO oper_log 
          (title, business_type, method, request_method, oper_name, 
           oper_url, oper_ip, oper_param, json_result, status, error_msg)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
      `;

      const [result] = await connection.execute<ResultSetHeader>(statement, [
        operLog.title,
        operLog.business_type,
        operLog.method,
        operLog.request_method,
        operLog.oper_name,
        operLog.oper_url,
        operLog.oper_ip,
        operLog.oper_param?.substring(0, 2000) || null,
        operLog.json_result || null,
        operLog.status,
        operLog.error_msg?.substring(0, 2000) || null,
      ]);

      return {
        id: result.insertId,
        ...operLog,
        oper_time: new Date().toISOString(),
      };
    } catch (error) {
      throw new Error("操作日志记录失败");
    }
  }

  // 批量删除操作日志
  async delete(ids: number[]) {
    try {
      const placeholders = ids.map(() => "?").join(",");
      const statement = `DELETE FROM oper_log WHERE id IN (${placeholders})`;

      const [result] = await connection.execute<ResultSetHeader>(
        statement,
        ids
      );
      return result.affectedRows > 0;
    } catch (error) {
      throw new Error("删除操作日志失败");
    }
  }

  // 清空操作日志
  async clean() {
    try {
      const statement = `TRUNCATE TABLE oper_log`;
      await connection.execute(statement);
      return true;
    } catch (error) {
      throw new Error("清空操作日志失败");
    }
  }

  // 获取操作日志列表
  async getList(
    params: API.OperLogList
  ): Promise<{ list: API.OperLogItem[]; total: number }> {
    try {
      const conditions: string[] = [];
      const values: any[] = [];
      Object.entries(params).map(([key, value]) => {
        if (value && key !== "current" && key !== "pageSize") {
          if (key === "startTime") {
            conditions.push("oper_time >= ?");
            values.push(value);
          }
          if (key === "endTime") {
            conditions.push("oper_time <= ?");
            values.push(value);
          }
          if (typeof value === "string") {
            conditions.push(`${key} LIKE ?`);
            values.push(`%${value}%`);
          } else {
            conditions.push(`${key} = ?`);
            values.push(value);
          }
        }
      });

      const whereClause =
        conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
      console.log(whereClause);
      // 查询总数
      const countStatement = `SELECT COUNT(*) as total FROM oper_log ${whereClause}`;
      const [countResult] = await connection.execute<RowDataPacket[]>(
        countStatement,
        values
      );
      const total = countResult[0].total;

      const listStatement = `
        SELECT * FROM oper_log 
        ${whereClause}
        ORDER BY oper_time DESC
        LIMIT ? OFFSET ?
      `;

      const pageSize = params.pageSize || 10;
      const offset = ((params.current || 1) - 1) * pageSize;

      const [listResult] = await connection.execute<RowDataPacket[]>(
        listStatement,
        [...values, pageSize.toString(), offset.toString()]
      );

      return {
        list: listResult as API.OperLogItem[],
        total,
      };
    } catch (error) {
      throw new Error("获取操作日志列表失败");
    }
  }

  // 获取客户端IP
  getClientIP(ctx: Context) {
    return (
      ctx.ip ||
      ctx.request.ip ||
      (ctx.request.headers["x-forwarded-for"] as string)?.split(",")[0] ||
      "unknown"
    );
  }
}

export default new OperLogService();
